/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package descente;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Hippolyte
 */
public class Recuit {
    
    public static Fenetre f;
    
    public static ArrayList<Point> villes = new ArrayList<>();
    
    public static ArrayList<Point> sTemp = new ArrayList<>();

    public static void main(String[] args) {
//        ArrayList<Point> villes = commerce.init(10);
//        ArrayList<Point> villes = new ArrayList<>();
        
        f = new Fenetre();
//        try {
//            Thread.sleep(2000);
//        } catch (InterruptedException ex) {
//            Logger.getLogger(Recuit.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        
        villes = commerce.init(1000);
        
//        villes.add(new Point(1, 3, "A"));
//        villes.add(new Point(1, 1, "B"));
//        villes.add(new Point(3, 1, "C"));
//        villes.add(new Point(3, 3, "D"));
        
        commerce.afficher(villes);
        recuit(villes);
    }

    private static float f(ArrayList<Point> villes) {
//        return Descente.f2(s);
        return commerce.coutChemin(villes);
//        return Rastrigin(0,0);
    }

    private static float Rastrigin(float x, float y) {
        return 20 + x * x + y * y - 10 * (float) (Math.cos(2 * Math.PI * x) + Math.cos(2 * Math.PI * y));

    }

    private static float V(float s) {
        float pas = 0.01f;
        return Math.round(Math.random() * (s - pas) + (s + pas));
    }

    private static void recuit(ArrayList<Point> s) {
        int nIter;
        int nGel;
        boolean accept;
        float zStar;
        ArrayList<Point> sStar;

//        ArrayList<Point> sTemp;

        int maxIter;
        int maxGel;
        float precision;
        float T;
        float k;
        float p;

        float deltaF;



        nIter = 0;
        nGel = 0;

        zStar = f(s);
        sStar = s;

        //parametres de l'algo
        maxIter = 1000000;
        maxGel = 150;
        precision = 0.0000000000000000000000f;
        k = 0.9995f;
        T = 1;

        while (T > precision && nIter != maxIter && nGel != maxGel) {
            
//            try {
//                Thread.sleep(20);
//            } catch (InterruptedException ex) {
//                Logger.getLogger(Recuit.class.getName()).log(Level.SEVERE, null, ex);
//            }
  
            nIter++;
//            sTemp = V(s);
            sTemp = commerce.inverse2(s);

            deltaF = f(sTemp) - f(s);

            if (deltaF < 0) {
                accept = true;
            } else {
                p = (float) Math.random();
                if (p <= Math.exp(-deltaF / T)) {
                    accept = true;
                } else {
                    accept = false;
                }
            }

            if (accept) {
                if (deltaF == 0) {
                    //rebond sur place
                    nGel++;
                } else {
                    nGel = 0;
                }
                if (f(sTemp) < zStar) {
                    zStar = f(sTemp);
                    sStar = sTemp;
                }
                s = sTemp;
            }
            T = k * T;
        }

        System.out.println("T > precision ==> " + (T > precision));

        System.out.println("nIter != maxIter ==> " + (nIter != maxIter));
        System.out.println("nGel != maxGel ==> " + (nGel != maxGel));

        System.out.println("T = " + T);
        System.out.println("nIter = " + nIter);
        System.out.println("nGel = " + nGel);


        System.out.println("meilleur coup = " + zStar + " \nmeilleur solution ="); 
        commerce.afficher(sStar);
        
        sTemp = sStar;
    }
}
